package com.m2dl.tpcsa.touchmycircle;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;

import com.m2dl.tpcsa.touchmycircle.common.Circle;
import com.m2dl.tpcsa.touchmycircle.common.Score;

public class TMCGame extends Activity {

	/** The GIF path. */
	protected final String GIF_PATH = "file:///android_asset/bulltrout.gif";
	/** The file persistent path. */
	protected final String PREFS_SCORE = "file";
	/** The circle game. */
	protected Circle circleGame = null;
	/** The unique handler instance of the TMCGame. */
	protected Handler myHandler = null;
	/** The metrics of the mobile screen. */
	protected int height, width;
	/** The textView for the number of circle. */
	protected TextView nbCircleTextView;
	/** The current score game. */
	protected Score currentScore;
	/** Indicates if the game is finish. */
	protected boolean finishTmcGame = false;
	/** The utilities to persist the data file. */
	protected SharedPreferences pref = null;
	protected SharedPreferences.Editor prefsEditor = null;
	/** The GIF handler. */
	protected WebView gif = null;
	/** The music handler. */
	protected MediaPlayer mediaPlayer = null;
	/** The indication of finish. */

	/**
	 * Changes the radius of the circle each 1 ms.
	 */
	private Runnable mUpdateTimeTask = new Runnable() {

		public void run() {
			if (finishTmcGame || (circleGame.getNbCircle() == 0)) {
				isEndOfTmcGame();
			} else {
				finishTmcGame = circleGame.reduceExternalRadius();
				nbCircleTextView.setText("Circle: " + circleGame.getNbCircle());
				circleGame.invalidate();
				// Launch again the handler
				myHandler.postDelayed(this, 10);
			}
		}
	};

	/**
	 * OnTouchListener for the circle. When the Circle is touch, the score
	 * persisted.
	 */
	private OnTouchListener myListener = new OnTouchListener() {
		private double newXSquared = 0.0;
		private double newYSquared = 0.0;
		private float newRadius = 0;
		private float theExternalRadius = 0;

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if (event.getAction() == 0) {
				this.theExternalRadius = (int) circleGame.getExternalRadius();
				this.newXSquared = Math.pow(circleGame.getPositionXCenter()
						- event.getX(), 2);
				this.newYSquared = Math.pow(circleGame.getPositionYCenter()
						- event.getY(), 2);
				this.newRadius = (float) Math.sqrt(newXSquared + newYSquared);

				if (this.newRadius <= this.theExternalRadius) {
					currentScore.addAScore((int) this.theExternalRadius);
					((Vibrator) getSystemService(Context.VIBRATOR_SERVICE))
							.vibrate(200);
					finishTmcGame = circleGame.changeCircle();
					circleGame.invalidate();
				} else {
					currentScore.addAScore(0);
					Toast.makeText(TMCGame.this, "Try Again!",
							Toast.LENGTH_LONG).show();
				}
			}
			return true;
		}
	};

	@SuppressLint("WorldReadableFiles")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_tmcgame);

		// Initialize the current score
		this.pref = this.getSharedPreferences(PREFS_SCORE, MODE_WORLD_READABLE);
		this.prefsEditor = pref.edit();
		this.currentScore = new Score();

		// Initialization of the circle
		this.circleGame = (Circle) findViewById(R.id.circleGame);

		/** Find the height and the width of the screen. */
		ViewTreeObserver vto = this.circleGame.getViewTreeObserver();
		vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			@SuppressWarnings("deprecation")
			@Override
			public void onGlobalLayout() {
				height = circleGame.getHeight() - 150;
				width = circleGame.getWidth() - 150;
				circleGame.setMaxScreen(width, height);
				ViewTreeObserver obs = circleGame.getViewTreeObserver();
				obs.removeGlobalOnLayoutListener(this);
			}

		});
		this.circleGame.setOnTouchListener(myListener);
		

		// Initialize the current GIF
		this.gif = (WebView) findViewById(R.id.tmcgame_webview);
		this.gif.loadUrl(GIF_PATH);
		// Initialization of the handler
		this.myHandler = new Handler();
		this.myHandler.postDelayed(mUpdateTimeTask, 1);

		// Manages the nbCircle
		this.circleGame.setNbCircle(20);
		this.nbCircleTextView = (TextView) findViewById(R.id.tmcgame_string_circle);
		this.nbCircleTextView.setBackgroundColor(Color.RED);
		String nbCircle = "Circle: " + this.circleGame.getNbCircle();
		this.nbCircleTextView.setText(nbCircle);

		// Manages the sound game
		this.mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.sound);
		this.mediaPlayer.setLooping(true);
		this.mediaPlayer.start();
	}

	/** Write the new score in order to persist it. */
	private void persisteScore(int score) {
		// Write the score
		if (pref.getInt("score", 0) < score) {
			prefsEditor.putInt("score", score);
		}
		prefsEditor.putInt("newScore", score);
		prefsEditor.commit();
	}

	/** Test if the game is finished. */
	private void isEndOfTmcGame() {
		persisteScore(this.currentScore.computeScore());
		this.mediaPlayer.stop();
		System.exit(RESULT_OK);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_tmcgame, menu);
		return true;
	}

	@Override
	public void onStop() {
		super.onStop();
		isEndOfTmcGame();
		this.finish();
	}

	/**
	 * Show the different items of the menu provide.
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.tmcg_quitter:
			mediaPlayer.stop();
			this.finish();
			return true;
		case R.id.tmcg_retourAccueil:
			Intent intent = new Intent(TMCGame.this, Accueil.class);
			startActivity(intent);
			return true;
		}

		return false;
	}
}
